package com.zj.demo.advice;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import com.zj.demo.anno.Decrypt;
import com.zj.demo.config.EncryptConfig;
import com.zj.demo.utils.DESUtil;
import com.zj.demo.utils.JsonUtils;

/**
 * @author 作者 zj:
 * @version 创建时间：2019年4月9日 上午10:16:36
 * 类说明
 */
@ControllerAdvice
public class RequestBodyEncryptAdvice implements RequestBodyAdvice {
	
	private Logger logger = LoggerFactory.getLogger(RequestBodyEncryptAdvice.class);
	
	@Autowired
	private EncryptConfig encryptConfig;

	@Override
	public boolean supports(MethodParameter methodParameter, Type type,
			Class<? extends HttpMessageConverter<?>> aClass) {
		return true;
	}

	@Override
	public Object handleEmptyBody(Object body,
			HttpInputMessage httpInputMessage, MethodParameter methodParameter,
			Type type, Class<? extends HttpMessageConverter<?>> aClass) {
		return body;
	}

	@Override
	public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage,
			MethodParameter methodParameter, Type type,
			Class<? extends HttpMessageConverter<?>> aClass) throws IOException {

		if(methodParameter.getMethod().isAnnotationPresent(Decrypt.class) && ! encryptConfig.isDebug()){
			try{
				return new MyHttpInputMessage(inputMessage);
			}catch(Exception e){
				e.printStackTrace();
				throw new RuntimeException("请求解密失败");
			}
		}
		
		return inputMessage;

	}

	@Override
	public Object afterBodyRead(Object body, HttpInputMessage httpInputMessage,
			MethodParameter methodParameter, Type type,
			Class<? extends HttpMessageConverter<?>> aClass) {
		// 校验数据？
		String reqStr = JsonUtils.toJson(body);
		logger.debug("=====req json===="+reqStr);
		return body;
	}
	
	class MyHttpInputMessage implements HttpInputMessage {
		private HttpHeaders headers;

		private InputStream body;

		public MyHttpInputMessage(HttpInputMessage inputMessage)
				throws Exception {
			this.headers = inputMessage.getHeaders();
			this.body = IOUtils.toInputStream(
					DESUtil.decrypt(IOUtils.toString(
							inputMessage.getBody(), "UTF-8"),encryptConfig.getEncryptKey()), "UTF-8");
//			this.body = IOUtils.toInputStream(
//				new String(	DESUtil.decrypt(IOUtils.toByteArray(
//							inputMessage.getBody()),encryptConfig.getEncryptKey().getBytes()), "UTF-8"));
		}

		@Override
		public InputStream getBody() throws IOException {
			return body;
		}

		@Override
		public HttpHeaders getHeaders() {
			return headers;
		}
	}

}
